package com.dcy.system.biz.config;

import cn.hutool.core.lang.TypeReference;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.StrUtil;
import com.dcy.common.constant.Constant;
import com.dcy.db.mybatis.model.DataColumnProperty;
import com.dcy.db.mybatis.model.DataScopeProperty;
import com.dcy.db.mybatis.model.DataScopeRoleModel;
import com.dcy.db.mybatis.service.AbstractDataScopeProvider;
import com.dcy.db.mybatis.service.IDataScopeProvider;
import com.dcy.db.mybatis.service.IDataScopeService;
import lombok.extern.slf4j.Slf4j;
import net.sf.jsqlparser.expression.Parenthesis;
import net.sf.jsqlparser.expression.StringValue;
import net.sf.jsqlparser.expression.operators.conditional.AndExpression;
import net.sf.jsqlparser.expression.operators.relational.ExpressionList;
import net.sf.jsqlparser.expression.operators.relational.InExpression;
import net.sf.jsqlparser.expression.operators.relational.ItemsList;
import net.sf.jsqlparser.schema.Column;
import net.sf.jsqlparser.statement.select.PlainSelect;
import org.apache.dubbo.rpc.RpcContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Author：dcy
 * @Description: 数据权限处理
 * @Date: 2021/9/9 14:17
 */
@Slf4j
@Configuration
public class DataScopeConfig {

    @Autowired
    private IDataScopeService iDataScopeService;

    @Bean
    public IDataScopeProvider dataScopeProvider() {
        return new AbstractDataScopeProvider() {
            @Override
            public void setWhere(DataScopeProperty dataScope, PlainSelect plainSelect) {
                final String userId = RpcContext.getContext().getAttachment(Constant.USER_ID);
//                log.info(userId);
//                log.info(plainSelect.toString());
//                log.info(dataScope.toString());
                if (StrUtil.equals(dataScope.getType(), "dev")) {
                    for (DataColumnProperty dataColumn : dataScope.getColumns()) {
                        if (StrUtil.equals(dataColumn.getName(), "dept_id")) {
                            final Map<String, Object> allDataScopeFlagAndData = iDataScopeService.getAllDataScopeFlagAndDataByUserId(userId);
                            final Boolean allDataScope = MapUtil.getBool(allDataScopeFlagAndData, IDataScopeService.ALL_DATA_SCOPE_FLAG);
                            if (!allDataScope) {
                                // 有数据范围
                                List<DataScopeRoleModel> roleList = MapUtil.get(allDataScopeFlagAndData, IDataScopeService.ROLE_LIST, new TypeReference<List<DataScopeRoleModel>>() {
                                });
                                Set<String> dataScopeList = iDataScopeService.getDateScopeDeptIds(userId, roleList);
                                ItemsList itemsList = new ExpressionList(dataScopeList.stream().map(StringValue::new).collect(Collectors.toList()));
                                InExpression inExpression = new InExpression(new Column(dataColumn.getAliasName()), itemsList);
                                if (null == plainSelect.getWhere()) {
                                    // 不存在 where 条件
                                    plainSelect.setWhere(new Parenthesis(inExpression));
                                } else {
                                    // 存在 where 条件 and 处理
                                    plainSelect.setWhere(new AndExpression(plainSelect.getWhere(), inExpression));
                                }
                            }
                        }
                    }
                }

            }
        };
    }
}
